// This code is in the public domain -- castanyo@yahoo.es

#ifndef NV_MESH_BASEMESH_H
#define NV_MESH_BASEMESH_H

#include <nvcore/Containers.h>
#include <nvmath/Vector.h>
#include <nvmesh/nvmesh.h>

namespace nv
{

/// Base mesh without connectivity.
class BaseMesh
{
public:
	struct Vertex;
	
	BaseMesh() {}

	BaseMesh(uint vertexNum) :
		m_vertexArray(vertexNum) {}
	
	// Vertex methods.
	uint vertexCount() const { return m_vertexArray.count(); }
	const Vertex & vertexAt(uint i) const { return m_vertexArray[i]; }
	Vertex & vertexAt(uint i) { return m_vertexArray[i]; }
	const Array<Vertex> & vertices() const { return m_vertexArray; }
	Array<Vertex> & vertices() { return m_vertexArray; }

	friend Stream & operator<< (Stream & s, BaseMesh & obj);

protected:
	
	Array<Vertex> m_vertexArray;
};


/// BaseMesh vertex.
struct BaseMesh::Vertex
{
	Vertex() : id(NIL), pos(zero), nor(zero), tex(zero) {}
	
	uint id;		// @@ Vertex should be an index into the vertex data.
	Vector3 pos;
	Vector3 nor;
	Vector2 tex;
};

inline bool operator==(const BaseMesh::Vertex & a, const BaseMesh::Vertex & b)
{
	return a.pos == b.pos && a.nor == b.nor && a.tex == b.tex;
}

inline bool operator!=(const BaseMesh::Vertex & a, const BaseMesh::Vertex & b)
{
	return a.pos != b.pos && a.nor != b.nor && a.tex != b.tex;
}

template <> struct hash<BaseMesh::Vertex>
{
	uint operator()(const BaseMesh::Vertex & v) const
	{
		return hash<Vector3>()(v.pos);
	}
};

} // nv namespace

#endif // NV_MESH_BASEMESH_H
